import asyncio
import json
import os
import random
import string
import sys

import aiohttp
import requests
from loguru import logger
def generate_random_string(length=10):
    """生成指定长度的随机字符串，包含字母和数字"""
    characters = string.ascii_letters + string.digits  # 字母和数字
    return ''.join(random.choice(characters) for _ in range(length))

async def generate_email(config):
    email_host = config['email_host']
    api_url = email_host + "/api/user/insert"
    token = config['custom_email_config']['token']
    default_password = config['custom_email_config'].get('default_password', '')

    random_username = generate_random_string(10)
    email = f"{random_username}@xixi1688.com"

    if not default_password:
        default_password = generate_random_string(10)

    data = {
        'username': email,
        'token': token,
        'password': default_password
    }

    loop = asyncio.get_event_loop()
    response = await loop.run_in_executor(None, lambda: requests.post(url=api_url, data=data))
    return response, email, default_password


class YesCaptchaSolver:
    def __init__(self, client_key, api_url='https://api.yescaptcha.com'):
        self.client_key = client_key
        self.api_url = api_url
    async def create_task(self, website_url, website_key, task_type="RecaptchaV2EnterpriseTaskProxyless",
                          enterprise_payload=None):
        """
        创建识别任务。
        """
        url = f"{self.api_url}/createTask"
        payload = {
            "clientKey": self.client_key,
            "task": {
                "type": task_type,
                "websiteURL": website_url,
                "websiteKey": website_key
            }
        }
        if enterprise_payload:
            payload['task']['enterprisePayload'] = enterprise_payload

        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=payload) as response:
                result = await response.json()
                if result.get('errorId') == 0:
                    return result.get('taskId')
                else:
                    raise Exception(f"错误 {result.get('errorCode')}: {result.get('errorDescription')}")

    async def create_img_task(self, question, image, task_type="FunCaptchaClassification", enterprise_payload=None):
        """
        创建识别任务。
        """
        url = f"{self.api_url}/createTask"
        payload = {
            "clientKey": self.client_key,
            "task": {
                "type": task_type,
                "image": image,
                "question": question
            }
        }

        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=payload) as response:
                result = await response.json()
                if result.get('errorId') == 0:
                    return result.get('taskId')
                else:
                    raise Exception(f"错误 {result.get('errorCode')}: {result.get('errorDescription')}")

    async def get_task_result(self, task_id, max_attempts=10, interval=10):
        """
        获取识别结果。
        """
        url = f"{self.api_url}/getTaskResult"
        payload = {
            "clientKey": self.client_key,
            "taskId": task_id
        }

        async with aiohttp.ClientSession() as session:
            for attempt in range(max_attempts):
                async with session.post(url, json=payload) as response:
                    result = await response.json()
                    if result.get('errorId') == 0:
                        status = result.get('status')
                        if status == 'ready':
                            return result.get('solution').get('objects')
                        elif status == 'processing':
                            logger.info(f"processing 等待中「{interval}」秒")
                            await asyncio.sleep(interval)
                        else:
                            raise Exception(f"未知的状态: {status}")
                    else:
                        raise Exception(f"错误 {result.get('errorCode')}: {result.get('errorDescription')}")
            raise Exception("获取结果超时，请稍后重试。")

    async def submit_captcha(self, submit_url, g_recaptcha_response, additional_data=None):
        """
        提交验证码到目标网站进行验证。
        """
        data = {
            "g-recaptcha-response": g_recaptcha_response
        }
        if additional_data:
            data.update(additional_data)
        async with aiohttp.ClientSession() as session:
            async with session.post(submit_url, data=data) as response:
                if response.status == 200:
                    return await response.text()
                else:
                    raise Exception(f"提交失败，HTTP状态码: {response.status}")


class EmailAPI:
    def __init__(self, email_host, token):
        self.email_host = email_host
        self.token = token
        self.api_base_url = f"{email_host}/api"

    async def create_email_account(self, email, password):
        """
        创建邮箱账户
        """
        url = f"{self.api_base_url}/user/insert"

        payload = {
            'username': email,
            'token': self.token,
            'password': password
        }

        async with aiohttp.ClientSession() as session:
            async with session.post(url, data=payload) as response:
                result = await response.json()
                if response.status == 200:
                    return {
                        'success': True,
                        'data': result,
                        'password': password
                    }
                else:
                    return {
                        'success': False,
                        'error': f"创建失败，HTTP状态码: {response.status}",
                        'response': result
                    }

def get_extension_path(extension_name):
    if getattr(sys, 'frozen', False):
        # 如果是打包后的可执行文件
        base_path = os.path.join(sys._MEIPASS, 'extensions')
    else:
        # 如果是开发环境
        base_path = os.path.join(os.path.dirname(__file__), 'extensions')

    extension_path = os.path.join(base_path, extension_name)

    if os.path.exists(extension_path):
        return extension_path
    else:
        print(f"警告: 插件 '{extension_name}' 不存在于路径 '{extension_path}'")
        return None

def modify_extension_config(extension_path, client_key):
    config_path = os.path.join(extension_path, 'config.js')

    with open(config_path, 'r') as f:
        content = f.read()

    config_start = content.index('const config = ')
    config_end = content.index('// 以下代码请勿修改')
    config_str = content[config_start:config_end].strip().rstrip(',')

    config = eval(config_str.replace('const config = ', ''))

    config['clientKey'] = client_key
    config['autorun'] = True

    new_config_str = f"const config = {json.dumps(config, indent=4)}"
    new_content = content[:config_start] + new_config_str + content[config_end:]

    with open(config_path, 'w') as f:
        f.write(new_content)